/*
 * Protocolo_NIPC.c
 *
 *  Created on: 22/10/2011
 *      Author: utn_so
 */


#include "Protocolo_NIPC.h"

//char* mensaje();

int handshakePPD(int socket, char* identificador_disco) {
	paquete *NIPC;
	NIPC = (paquete*) malloc(sizeof(paquete));
	NIPC->type = 1;
	NIPC->payload_Length = strlen(identificador_disco);
	strcpy(NIPC->payload, identificador_disco);
	send(socket, NIPC, sizeof(paquete), 0);
	paquete *recibirNIPC;
	recibirNIPC = (paquete*) malloc(sizeof(paquete));
	int length_recibido, resultado_operacion;
	length_recibido = recv(socket, recibirNIPC, sizeof(paquete), 0);
	if (recibirNIPC->type == 0 && recibirNIPC->payload_Length == 0) {
		resultado_operacion = 0; /* la conexion fue exitosa */
	} else {
		if (recibirNIPC->type == 0 && recibirNIPC->payload_Length != 0) {
			resultado_operacion = 1;
			printf("%s", (char*) recibirNIPC->payload);
		}
	}
	return resultado_operacion;
}

int handshakePRAID_PPD(int socket, paquete *NIPC) {
	paquete *enviarNIPC;
	int resultado;
	enviarNIPC = (paquete*) malloc(sizeof(paquete));
	if (NIPC->type == 0) {
		enviarNIPC->type = 0;
		strcpy(enviarNIPC->payload, "");
		enviarNIPC->payload_Length = strlen(enviarNIPC->payload); /*si la conexion es correcta */
		send(socket, enviarNIPC, sizeof(paquete), 0);
		resultado = 1;
		return resultado;
	} else { /*si la conexion es incorrecta */
		enviarNIPC->type = 0;
		strcpy(enviarNIPC->payload, "Se produjo un error en la conexion\n");
		enviarNIPC->payload_Length = strlen(enviarNIPC->payload);
		send(socket, enviarNIPC, sizeof(paquete), 0);
		close(socket);
	}
	resultado = 1;
	return resultado;
}

int handshakeFS_PPD(int socket, paquete *NIPC){
	paquete *enviarNIPC;
	int resul;
	enviarNIPC = (paquete*)malloc(sizeof(paquete));
	if(NIPC->type==0){
		enviarNIPC->type = 0;
		strcpy(enviarNIPC->payload,"");/*si la conexion es correcta */
		enviarNIPC->payload_Length = 0;
		send(socket, enviarNIPC, sizeof(paquete), 0);
		resul=0;
	}
	else{                                             /* si la conexion es incorrecta */
		enviarNIPC->type = 0;
		strcpy(enviarNIPC->payload,"Se produjo un error en la conexion\n");
		enviarNIPC->payload_Length = strlen(enviarNIPC->payload);
		send(socket, enviarNIPC, sizeof(paquete), 0);
        resul=1;
	}
	return resul;
}

uint8_t conectarse_RAID(char* DIRECCION_IP, uint16_t PUERTO,
		char* IDENTIFICADOR_DISCO)

{

	uint8_t sockfd, handshake_OK;
	paquete *NIPC_Prueba;
	NIPC_Prueba = (paquete *) malloc(sizeof(paquete));
	int len;
	struct sockaddr_in address;
	int result;

	/* Crear un socket para el cliente */

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	memset(&address, 0, sizeof(address));
	address.sin_family = AF_INET;
	address.sin_addr.s_addr = inet_addr(DIRECCION_IP);
	address.sin_port = PUERTO;
	len = sizeof(address);

	result = connect(sockfd, (struct sockaddr *) &address, len);

	if (result == -1) {
		perror("ERROR EN LA CONEXION");
		exit(1);
	}

	handshake_OK = handshakePPD(sockfd, IDENTIFICADOR_DISCO);

	if (!handshake_OK) close(sockfd);
	return sockfd;
}

void enviarSector(uint8_t socket, t_sector sector){
	paquete *NIPC;
	NIPC = (paquete*) malloc(sizeof(paquete));
	memcpy(NIPC->payload,sector.datos,512);
	NIPC->nro_Sector = sector.numero;
	NIPC->type = sector.type;
	send(socket, NIPC, sizeof(paquete), 0);
	free(NIPC);
}

t_sector recibirSector(uint8_t socket){
	t_sector sector;
	paquete *NIPC;
	NIPC = (paquete*) malloc(sizeof(paquete));
	recv(socket, NIPC, sizeof(paquete), 0);
	memcpy(sector.datos,NIPC->payload,512);
	sector.numero = NIPC->nro_Sector;
	sector.type = NIPC->type;
	free(NIPC);
	return sector;
}

uint8_t conectarse_FS(char* DIRECCION_IP,uint16_t PUERTO,char* IDENTIFICADOR_DISCO){
	uint8_t server_sockfd, client_sockfd;
	unsigned int server_len;
	struct sockaddr_in server_address;
	struct sockaddr_in client_address;
	server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
	memset(&server_address, 0, sizeof(server_address));
	server_address.sin_family = AF_INET;
	server_address.sin_addr.s_addr = inet_addr(DIRECCION_IP);
	server_address.sin_port = PUERTO;
	server_len = sizeof(server_address);
	bind(server_sockfd, (struct sockaddr *) &server_address, server_len);
	listen(server_sockfd, 1);
	printf("listen\n");
	int n;
	unsigned int client_len;
	client_len = sizeof(client_address);
	client_sockfd = accept(server_sockfd, (struct sockaddr *) &client_address,&client_len);
	printf("Connected\n");
	paquete *paquete_R_NIPC;
	paquete_R_NIPC = (paquete*) malloc(sizeof(paquete));
	n = recv(client_sockfd, paquete_R_NIPC, sizeof(paquete), 0);
	int resultado_handshake;
	printf("recibi bien ");
	resultado_handshake=handshakeFS_PPD(client_sockfd, paquete_R_NIPC);
    if (!resultado_handshake) {
    	printf(" ");
        //close(client_sockfd);
    	}
	return client_sockfd;
	/*	if (n <= 0) {
					perror("recv");
		            exit(1);
	                }
	//printf("%i\n", paquete_R_NIPC->type);
	//printf("%i\n", paquete_R_NIPC->payload_Length);
	//printf("%s\n", paquete_R_NIPC->payload);


	paquete *paquete_ENV_NIPC;

	if (resultado_handshake == 1) {
		printf("Salio bien la operacion\n");
		//hilo para meter en la cola
		//hilo para sacar de la cola
		int DescriptorArchivo;

		char *sector;

		struct stat estado_arch;
		DescriptorArchivo = abrirArchivo(FILEPATH, &estado_arch);
		n = recv(client_sockfd, paquete_R_NIPC, sizeof(paquete), 0);
							if (n <= 0) {
							perror("recv");
				            exit(1);
			                }
		if(paquete_R_NIPC->type==Lectura){

		sector=leerSector(paquete_R_NIPC->nroSector, estado_arch, DescriptorArchivo);

		paquete_ENV_NIPC->type= 1;
		memcpy(paquete_ENV_NIPC->payload,sector,512);si la conexion es correcta
		paquete_ENV_NIPC->payload_Length = 512;
		send(client_sockfd, paquete_ENV_NIPC, sizeof(paquete), 0);
		}

		printf("Se envio el sector correctamente\n");
	}
	else {
		printf("Salio mal la operacion\n");
		close(client_sockfd);
	}*/

	close(server_sockfd);
	return resultado_handshake;

}
